package com.settlement.system.common.util;

import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.settlement.system.common.enums.ObjectMapperInstance;
import com.settlement.system.common.model.QyWechatData;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

public class HttpUtils {

    private static final RestTemplate restTemplate = new RestTemplate();

    private final static Logger logger = LoggerFactory.getLogger(HttpUtils.class);

    private static final ObjectMapper objectMapper = ObjectMapperInstance.INSTANCE.getObjectMapper();

    public static void sendToQyWechat(QyWechatData params, String url) {
        HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost(url);
        post.setHeader("Content-Type", "application/json");
        String result;
        InputStream inStream = null;
        try {
            logger.info(String.format("发送数据到企业微信:%s", objectMapper.writeValueAsString(params)));
            StringEntity s = new StringEntity(objectMapper.writeValueAsString(params), "utf-8");
            s.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,
                    "application/json"));
            post.setEntity(s);
            // 发送请求
            HttpResponse httpResponse = client.execute(post);
            // 获取响应输入流
            inStream = httpResponse.getEntity().getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    inStream, StandardCharsets.UTF_8));
            StringBuilder strber = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null)
                strber.append(line).append("\n");

            result = strber.toString();
            logger.info(String.format("企业微信返回：%s", result));
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                logger.info("请求服务器成功，做相应处理");
            } else {
                logger.info("请求服务端失败");
            }
        } catch (Exception e) {
            logger.info(String.format("发送数据到企业微信异常:%s", e.getMessage()));
            try{
                inStream.close();
            }catch (Exception ignored){}
            throw new RuntimeException(e);
        }
    }

    /**
     * 将MultiPartFile转化为File
     *
     * @param path
     * @param multiFile
     * @return
     * @throws IOException
     */
    public static File multiPartFileToFile(String path, MultipartFile multiFile) throws IOException {
        File file = new File(path);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        file.createNewFile();
        multiFile.transferTo(file);
        return file;
    }

    public static ResponseEntity<String> uploadFile(String fileName, MultipartFile file, long fileLen, String postUrl) throws Exception {
        // 1、封装请求头
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("multipart/form-data");
        headers.setContentType(type);
        headers.setContentLength(fileLen);
        headers.setContentDispositionFormData("media", fileName);
        // 2、封装请求体
        MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
        String path = System.getProperty("user.dir") + File.separator + fileName;
        File tempFile = multiPartFileToFile(path, file);
        FileSystemResource resource = new FileSystemResource(tempFile);
        param.add("file", resource);
        // 3、封装整个请求报文
        HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(param, headers);
        ResponseEntity<String> stringResponseEntity = restTemplate.postForEntity(postUrl, httpEntity, String.class);
        tempFile.deleteOnExit();
        return stringResponseEntity;
    }

    /**
     * @param customerId 商家授权代码
     * @param method     接口名称：（订单：jushuitan.order.list.query，售后单：jushuitan.refund.list.query）
     * @param params
     * @return
     * @throws IOException
     */
    public static JSONObject invokeJSTApiForJSON(String customerId, String method, Map<String, Object> params) throws IOException {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String timestamp = df.format(new Date());
        params.put("method", method);
        String sign = JSTUtils.createSign(timestamp, customerId, params);
        params.put("sign", sign);
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        okhttp3.MediaType mediaType = okhttp3.MediaType.parse("application/x-www-form-urlencoded");
//        String content = "timestamp=%s&customer_id=%s&target_app_key=23060081&app_key=%s&method=%s&format=json&v=2.0&sign=%s&page_index=1&page_size=10&o_ids=%s&start_time=%s&end_time=%s&sign_method=md5"
//                .formatted(timestamp, customerId, JSTUtils.appKey, method, sign, orderNo, startTime, endTime);
        List<String> paramList = new ArrayList<>();
        for (String key : params.keySet()) {
            if (StringUtils.hasText(key) && Objects.nonNull(params.get(key)) && StringUtils.hasText(params.get(key).toString())) {
                paramList.add("%s=%s".formatted(key, params.get(key)));
            }
        }
        String content = String.join("&", paramList);
        RequestBody body = RequestBody.create(mediaType, content);
        Request request = new Request.Builder()
                .url("http://a1q40taq0j.api.taobao.com/router/qm")
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .build();
        Response response = client.newCall(request).execute();
        return JSONObject.parseObject(response.body().string());
    }
}
